﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using blackhouse.BlackApart.Data;
using blackhouse.BlackApart.Business.Calendar;

namespace blackhouse.BlackApart.Business.Apartments {
    public class DaApartment : IApartment {

        #region Fields

        private ImpApartment instance;
        private IApartmentDataAccess iDataApartment;
        private int locationId;
        private int groupId;

        #endregion

        #region Properties

        public int Id {
            get { return this.instance.Id; }
        }

        public int NumberOfPeople {
            get { return this.instance.NumberOfPeople; }
            set { this.instance.NumberOfPeople = value; }
        }

        public IApartmentLocation Location {
            get {
                if (this.instance.Location.Id == 0 && this.locationId > 0) // późne wiązanie, lokalizacja jest pobierana tylko wtedy, gdy jest potrzebna
                    this.instance.Location = Factory.Instance().GetApartmentLocation(this.locationId);
                return this.instance.Location;
            }
            set { this.instance.Location = value; }
        }

        public float AreaSize {
            get { return this.instance.AreaSize; }
            set { this.instance.AreaSize = value; }
        }

        public string Name {
            get { return this.instance.Name; }
            set { this.instance.Name = value; }
        }

        public IApartmentGroup Group {
            get {
                if ((this.instance.Group == null || this.instance.Group.Id == 0) && this.groupId > 0) // późne wiązanie, grupa jest pobierana tylko wtedy, gdy jest potrzebna
                    this.instance.Group = Factory.Instance().GetApartmentGroup(this.groupId);
                return this.instance.Group;
            }
            set { this.instance.Group = value; }
        }

        #endregion

        #region Constructors

        public DaApartment(IApartmentDataAccess iDataApartment) {
            this.iDataApartment = iDataApartment;
            this.instance = new ImpApartment();
        }

        public DaApartment(IApartmentDataAccess iDataApartment, int apartmentId) {
            this.iDataApartment = iDataApartment;
            this.instance = this.ConvertToInstance(this.iDataApartment.GetApartment(apartmentId));
        }

        public DaApartment(IApartmentDataAccess iDataApartment, ApartmentData data) {
            this.iDataApartment = iDataApartment;
            this.instance = this.ConvertToInstance(data);
        }

        #endregion

        #region Methods

        private ImpApartment ConvertToInstance(ApartmentData data) {
            ImpApartment apartment = new ImpApartment();
            apartment.AreaSize = data.AreaSize;
            this.groupId = data.GroupId;
            //apartment.Group = Factory.Instance().GetApartmentGroup(data.GroupId);
            apartment.Id = data.Id;
            this.locationId = data.LocationId;
            //apartment.Location = Factory.Instance().GetApartmentLocation(data.LocationId);
            apartment.Name = data.Name;
            apartment.NumberOfPeople = data.NumberOfPeople;
            return apartment;
        }

        public bool Save() {
            if (this.instance.Save()) {
                if (!this.Group.Save()) return false;
                if (!this.Location.Save()) return false;

                this.instance.Id = this.iDataApartment.SaveApartment(this.Id, this.Name, this.Group.Id, this.Location.Id, this.NumberOfPeople, this.AreaSize);
                return this.instance.Id > 0;
            }
            else
                return false;
        }

        //public ICalendar GetCalendar(DateTime startDate, DateTime endDate) {
        //    return this.instance.GetCalendar(startDate, endDate);
        //}

        public IApartment[] GetAllFreeApartments(DateTime startDate, DateTime endDate) {
            return this.GetAllFreeApartments(startDate, endDate, 0);
        }

        public IApartment[] GetAllFreeApartments(DateTime startDate, DateTime endDate, int apartmentGroupId) {
            return this.iDataApartment.GetFreeApartments(startDate, endDate, apartmentGroupId).Select(ad => new DaApartment(this.iDataApartment, ad)).ToArray();
        }

        public IApartment[] GetApartmentsByGroup(int groupId) {
            return this.iDataApartment.GetApartmentsByGroup(groupId).Select(ad => new DaApartment(this.iDataApartment, ad)).ToArray();
        }

        #endregion

        #region Equals Methods

        public override bool Equals(object obj) {
            return this.instance.Equals(obj);
        }

        public override int GetHashCode() {
            return this.instance.GetHashCode();
        }

        public override string ToString() {
            return this.instance.ToString();
        }

        #endregion

    }
}
